﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using System.Threading;
using com.fukefu.spider;
using com.fukefu.sql;
using com.fukefu.tools;

namespace com.fukefu.update.instantiated.MarketShare
{
    public class PM_Keyword : PM
    {
        BaiduSpider baidu = new BaiduSpider();
        Hashtable hs_url = new Hashtable();
        Queue<Title> queue_word = new Queue<Title>();

        string reg_paiming = "'p1':([0-9]+),\\s*'y':'[0-9a-zA-Z]+'\\s*}\\)\"\\s*href=\"([^\"]+)|id=\"([0-9]{1,2})\"[^>]+mu=\"([^\"]+)\"";

        public override void Init()
        {
            Display("------更新关键字排名------");
            Display("初始化中...");
            LoadURL();
            LoadUnfinishedKeyword();
            new MultiThread().Begin(new Preferences().GetInt("百度线程"), new ThreadStart(UpdateTodayKeywordRanking));
            Display("关键字排名更新结束...");
        }
        //加载所有网址
        private void LoadURL()
        {
            SqlDataReader re = sql.Query("select url,uid,times from [_pm_网址]");
            while (re.Read())
            {
                if (!hs_url.Contains(re["url"]))
                {
                    hs_url.Add(re["url"], re["uid"]);
                }
            }
            re.Close();
        }
        //加载未今天未采集的关键字
        private void LoadUnfinishedKeyword()
        {
            SqlDataReader re = sql.Query("select kid,word from [_bt_关键字] where datediff(d,[dt],getdate())>0 or dt is null");
            while (re.Read())
            {
                queue_word.Enqueue(new Title(re["kid"].ToString(), re["word"].ToString()));
            }
            re.Close();
            SetMaxNum(queue_word.Count);
        }
        //更新关键字排名
        private void UpdateTodayKeywordRanking()
        {
            Title k;
            do
            {
                //拉取下一个关键字
                lock (queue_word)
                {
                    if (queue_word.Count == 0)
                    {
                        break;
                    }
                    k = queue_word.Dequeue();
                }
                ProcessBaiduKeyword(k);
            } while (true);
            Display(Thread.CurrentThread.Name + " 结束...");
        }
        //处理一个百度返回的结果
        private void ProcessBaiduKeyword(Title k)
        {
            Display(k.Word + " 更新中...");
            string html, url, paiming, uid;
            SqlString cmd = new SqlString();
            html = baidu.GetHtml(k.Word, 30);
            MatchCollection mc = Regex.Matches(html, reg_paiming, RegexOptions.IgnoreCase);
            //删除今天的此关键字排名，目的抓取一半的时候程序退出
            cmd.Add("delete from [_pm_排名] where kid='" + k.KId + "' and [dt]=convert(varchar,getdate(),111)");
            foreach (Match m in mc)
            {
                GroupCollection gc = m.Groups;
                if (gc[1].Value.Equals(""))
                {
                    paiming = gc[3].Value;
                    url = gc[4].Value;
                }
                else
                {
                    paiming = gc[1].Value;
                    url = gc[2].Value;
                }
                //检测重复时候锁定
                lock (hs_url)
                {
                    if (hs_url.Contains(url))
                    {
                        uid = hs_url[url].ToString();
                    }
                    else
                    {
                        uid = Guid.NewGuid().ToString();
                        cmd.Add("insert into [_pm_网址]([uid],[url],[domain],[host]) values('" + uid + "','" + url + "','" + MyFunction.GetDomain(url) + "','" + MyFunction.GetHost(url) + "')");
                        hs_url.Add(url, uid);
                    }
                }
                cmd.Add("insert into [_pm_排名]([pm],[kid],[uid]) values(" + paiming + ",'" + k.KId + "','" + uid + "')");
            }
            cmd.Add("update [_bt_关键字] set dt=getdate() where kid='" + k.KId + "'");
            try
            {
                sql.Update(cmd.Read());
            }
            catch (Exception e)
            {
                Display("错误:" + e.Message);
            }
            SetNumAdd();
        }
    }
}
